package com.justgame.project.base.auth;


import com.auth0.jwt.JWT;
import com.justgame.project.base.utils.JdbcTemplateUtils;
import com.justgame.project.cloud.base.entity.CurrentUser;
import com.justgame.project.cloud.common.constant.Auth2Token;
import com.justgame.project.cloud.common.exception.Exc;
import com.justgame.project.cloud.common.util.ShiroUtils;
import com.justgame.project.cloud.common.util.TokenUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.util.*;


/**
 * 身份认证
 */
@Slf4j
@Component
public class Auth2Realm extends AuthorizingRealm {

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof Auth2Token;
    }

    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info(" - - - - - - - - 开始授权 - - - - - - - - ");
        Long userId = ShiroUtils.getUserIdElseThrow();
        log.info("UserID:{{}}", userId);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        CurrentUser entity = JdbcTemplateUtils.queryForAuthEntity(userId);
        log.info("Roles:{{}}", entity.getRole());
        info.setRoles(Set.of(entity.getRole().toLowerCase()));
        log.info(" - - - - - - - - 授权结束 - - - - - - - - ");
        return info;
    }


    /**
     * 验证业务逻辑
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //        获取TOKEN
        String accessToken = (String) token.getPrincipal();
        //        Token = 空
        if (StringUtils.isBlank(accessToken)) {
            Exc.Thorw(HttpStatus.UNAUTHORIZED);
        }
        Claims claims = TokenUtil.validateToken(accessToken).orElseThrow();
        Long userid = Long.valueOf(claims.getSubject());
        CurrentUser authEntity = JdbcTemplateUtils.queryForAuthEntity(userid);
        if (Objects.isNull(authEntity)) {
            Exc.Thorw(HttpStatus.UNAUTHORIZED);
        }else if (Boolean.TRUE.equals(authEntity.getLocked())) {
            Exc.Thorw(HttpStatus.FORBIDDEN);
        }

        // Token过期
        if (ShiroUtils.isExpiredToken(accessToken, userid)) {
           Exc.Thorw(HttpStatus.UNAUTHORIZED);
        }

        Date date = JWT.decode(accessToken).getExpiresAt();
        /* 换算成分 */
        long hours = new Date(System.currentTimeMillis() - date.getTime()).getHours();
        if (hours <= 1) {
            ShiroUtils.login(userid);
        }
        return new SimpleAuthenticationInfo(authEntity, accessToken, getName());
    }

}
